#define _XOPEN_SOURCE 500

#include <semaphore.h>

struct link_element{
		void *data;
		struct link_element *next;
};

typedef struct link_element t_link_element;


typedef struct{
		t_link_element *head;
		int elements_count;
}t_list;

typedef struct{
		void **data;
		int size;
}t_array;

typedef struct{
		char *text;
		void *context;
		void (*command_handler)(void*, t_array*);
}t_command;

typedef struct{
		t_list *commands;
		void *globalcontext;
		char startArgsToken;
		char endArgsToken;
		char startArgToken;
		char endArgToken;
		char separatorArgsToken;
}t_commands;


t_array    *array_create(int size);
void       *array_get( t_array *list, int num );
void       *array_switch( t_array* list, int num, void* data );
void            array_set( t_array* list, int num, void* data, void (*data_destroyer)(void*));
void*           array_find( t_array *list, int (*closure)(void*) );
void            array_iterator( t_array *list, void (*closure)(void*) );
void       *array_remove( t_array *list, int num );
void        array_removeAndDestroy( t_array *list, int num, void (*data_destroyer)(void*) );
void            array_removeByClosure( t_array *list, int (*closure)(void*), void (*data_destroyer)(void*) );
int             array_size( t_array *list );
void            array_clean( t_array *list, void (*data_destroyer)(void*) );
void            array_destroy( t_array *list, void (*data_destroyer)(void*) );
t_commands *commands_create(char startArgsToken, char endArgsToken, char separatorArgsToken);
t_commands *commands_createWithConext(void *context, char startArgsToken, char endArgsToken, char separatorArgsToken);
void commands_setStartEndArgTokens(t_commands *commandsmanager, char startArgToken, char endArgToken);
void commands_setStartEndArgsTokens(t_commands *commandsmanager, char startArgsToken, char endArgsToken);
char commands_getStartArgsTokens(t_commands *commandsmanager);
char commands_getEndArgsTokens(t_commands *commandsmanager);
void commands_setSeparatorArgsToken(t_commands *commandsmanager, char separatorArgsToken);
char commands_getSeparatorArgsToken(t_commands *commandsmanager);
void commands_add(t_commands *commands, const char *strcommand, void (*command_handler)(void*, t_array*));
void commands_addWithContext(t_commands *commands, void *context,const char *strcommand, void (*command_handler)(void*, t_array*));
int  commands_parser(t_commands *commands, char *strcommand);
void commands_destroy(t_commands *commands);
char    *scanner_getLine(char buff[], int num);
int      scanner_getNumberOfLines(char buff[]);
void     scanner_iterateLines(char buff[], void (*closure)(char*));
char    *scanner_findLine(char buff[], int (*closure)(char*));
int     scanner_starWith( char *str, char *prefix );
t_array *scanner_split1( char *str, const char sep, char startTokenDelimitor, char endTokenDelimitor);
t_array *scanner_split2( char *str, const char sep);
char    *scanner_trim( char str[] );
char    *scanner_trimInBuffer( char str[], char trim_str[], int max_size );
char    *scanner_getIpFromAddress( char str_adress[], char str_ip[] );
int              scanner_getPortFromAddress( char str_adress[] );
char    *scanner_getPortFromAddress2( char str_adress[], char str_port[] );
t_list *collection_list_create();
int collection_list_add( t_list *list, void *data );
void* collection_list_find( t_list *list, int (*closure)(void*));
void collection_list_destroy( t_list *list, void (*data_destroyer)(void*) );
void collection_list_clean( t_list *list, void (*data_destroyer)(void*) );
void array_clean( t_array *array, void (*data_destroyer)(void*) );
